package cave.ui;

import android.graphics.Color;
import cave.renderer.RenderList;
import cave.renderer.Texture;
import cave.utils.MathUtils;

public class TextField implements StaticUiItem {
	
	private static final char[] DIGIT_TO_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
	
	private float x, y;
	private float charWidth, charHeight;
	private float red, green, blue, alpha;
	private Font font;
	private Texture[] textures;
	private int length;
	
	public TextField(float x, float y, String text, Font font, float fontSize, int color) {
		this(x, y, text, font, fontSize, Color.red(color) / 255.0f, Color.green(color) / 255.0f,
				Color.blue(color) / 255.0f, Color.alpha(color) / 255.0f);		
	}
	
	public TextField(float x, float y, String text, Font font, float fontSize,
			float red, float green, float blue, float alpha) {
		this.x = x;
		this.y = y;
		this.font = font;
		this.red = red;
		this.green = green;
		this.blue = blue;
		this.alpha = alpha;
		charWidth = fontSize*font.getCharAspectRatio();
		charHeight = fontSize;
		
		length = text.length();
		textures = new Texture[length];
		
		for (int i = 0; i < text.length(); i++) {
			textures[i] = font.getTexture(text.charAt(i));
		}
		
	}

	@Override
	public void draw(RenderList renderList) {
		for (int i = 0; i < length; i++) {
			renderList.addScreenData(x+(i*charWidth), y, charWidth, charHeight,
					0, 1, textures[i], red, green, blue, alpha);
		}
	}

	@Override
	public void destroy() {}
	
	public void setText(String text) {
		length = text.length();
		
		alloc(length);
		
		for (int i = 0; i < length; i++) {
			textures[i] = font.getTexture(text.charAt(i));
		}
	}
	
	public void setInt(int value) {
		
		if (value == 0) {			
			length = 1;
			alloc(length);
			textures[0] = font.getTexture('0');

		} else if (value < 0) {
			value *= -1;
			
			int numDigits = (int)Math.log10((double)value) + 1;
			length = numDigits + 1;
			
			alloc(length);
			
			textures[0] = font.getTexture('-');
			
			for (int i = numDigits; i > 0; --i) {
				int digit = ((value % MathUtils.pow10(i)) - (value % MathUtils.pow10(i-1))) / MathUtils.pow10(i-1);
				textures[1 + numDigits - i] = font.getTexture(DIGIT_TO_CHAR[digit]);
			}
			
			
		} else {
			
			length = (int)Math.log10((double)value) + 1;
			
			alloc(length);
			
			for (int i = length; i > 0; --i) {
				int digit = ((value % MathUtils.pow10(i)) - (value % MathUtils.pow10(i-1))) / MathUtils.pow10(i-1);
				textures[length - i] = font.getTexture(DIGIT_TO_CHAR[digit]);
			}
			
		}
	
		
	}
	
	public void setFloat(float value, int numDecimals) {
		
		int index = 0;
		int integer = (int)value;
		int fraction = (int)((value - integer) * MathUtils.pow10(numDecimals));
		
		// Integer part
		if (integer == 0) {
			if (fraction < 0) {
				length = numDecimals + 3; 
				alloc(length);
				textures[0] = font.getTexture('-');
				textures[1] = font.getTexture('0');
				index += 2;
			} else {
				length = numDecimals + 2; 
				alloc(length);
				textures[0] = font.getTexture('0');
				index++;
			}
		} else {
			boolean negative = false;
			
			if (integer < 0) {
				negative = true;
				integer *= -1;
				index++;
			}
			
			int numIntegerDigits = (int)Math.log10((double)integer) + 1;
			length = index + numIntegerDigits + 1 + numDecimals;
			alloc(length);
			if (negative) {
				textures[0] = font.getTexture('-');
			}
			
			for (int i = numIntegerDigits; i > 0; --i) {
				int digit = ((integer % MathUtils.pow10(i)) - (integer % MathUtils.pow10(i-1))) / MathUtils.pow10(i-1);
				textures[index + numIntegerDigits - i] = font.getTexture(DIGIT_TO_CHAR[digit]);
			}
			index += numIntegerDigits;
		}
		
		textures[index++] = font.getTexture('.');
		
		// Fractional part
		fraction = Math.abs(fraction);
		if (fraction == 0) {
			for (int i = 0; i < numDecimals; ++i) {
				textures[index + i] = font.getTexture('0');
			}
		} else {
			int numFractionDigits = (int)Math.log10((double)fraction) + 1;
			for (int i = 0; i < numDecimals - numFractionDigits; ++i) {
				textures[index++] = font.getTexture('0');
			}
			for (int i = numFractionDigits; i > 0; --i) {
				int digit = ((fraction % MathUtils.pow10(i)) - (fraction % MathUtils.pow10(i-1))) / MathUtils.pow10(i-1);
				textures[index + numFractionDigits - i] = font.getTexture(DIGIT_TO_CHAR[digit]);
			}
		}
				
	}
	
	public void setPosition(float x, float y) {
		this.x = x;
		this.y = y;
	}
	
	public void setFontSize(float fontSize) {
		charWidth = fontSize*font.getCharAspectRatio();
		charHeight = fontSize;
	}
	
	public void setColor(float red, float green, float blue) {
		this.red = red;
		this.green = green;
		this.blue = blue;
	}
	
	public void setColor(float red, float green, float blue, float alpha) {
		this.red = red;
		this.green = green;
		this.blue = blue;
		this.alpha = alpha;
	}
	
	public void setAlpha(float alpha) {
		this.alpha = alpha;
	}
	
	public float getLength() {
		return charWidth * length;
	}
	
	private void alloc(int newLength) {
		if (newLength > textures.length) {
			textures = new Texture[newLength];
		} else {
			for (int i = 0; i < textures.length; i++) {
				textures[i] = null;
			}
		}
	}
	
}
